package com.shangyueshang.utils;

import com.shangyueshang.security.JwtAuthenticationToken;
import com.shangyueshang.security.JwtUserDetails;
import com.shangyueshang.service.SysUserService;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author: JokeyZheng
 * @email: zhengjingfeng@ruqimobility.com
 * @created: 2022/1/6 19:45
 * @version: v1.0.0
 */
public class SecurityUtil {
	
	private SecurityUtil() {
	}
	
	/**
	 * 系统登录认证
	 *
	 * @param request
	 * @param username
	 * @param password
	 * @param authenticationManager
	 * @return
	 */
	public static JwtAuthenticationToken login(
			HttpServletRequest request,
			String username,
			String password,
			AuthenticationManager authenticationManager
	) {
		JwtAuthenticationToken token = new JwtAuthenticationToken(username, password);
		token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
		//执行登录认证过程
		Authentication authentication = authenticationManager.authenticate(token);
		//认证成功存储认证信息到上下文
		SecurityContextHolder.getContext().setAuthentication(authentication);
		//生成令牌并返回给客户端
		token.setToken(JwtTokenUtil.createToken(authentication));
		token.setAuthorizedShops(((JwtUserDetails) authentication.getPrincipal()).getAuthorizedShops());
		return token;
	}
	
	/**
	 * 获取令牌进行认证
	 *
	 * @param request
	 */
	public static void checkAuthentication(HttpServletRequest request) {
		//从令牌token中获取登录认证信息
		Authentication authentication = JwtTokenUtil.getAuthenticationFromToken(request);
		//设置登录认证信息到上下文
		SecurityContextHolder.getContext().setAuthentication(authentication);
	}
	
	/**
	 * 获取当前登录信息
	 *
	 * @return
	 */
	public static Authentication getAuthentication() {
		if (Objects.isNull(SecurityContextHolder.getContext())) {
			return null;
		}
		return SecurityContextHolder.getContext().getAuthentication();
	}
	
	/**
	 * 获取当前用户名
	 *
	 * @return
	 */
	public static String getUsername() {
		String username = null;
		Authentication authentication = getAuthentication();
		if (Objects.nonNull(authentication)) {
			Object principal = authentication.getPrincipal();
			if (principal instanceof UserDetails) {
				username = ((UserDetails) principal).getUsername();
			} else {
				username = principal.toString();
			}
		}
		return username;
	}
	
	/**
	 * 从登录认证信息中获取用户名
	 *
	 * @param authentication
	 * @return
	 */
	public static String getUsername(Authentication authentication) {
		String username = null;
		Object principal = authentication.getPrincipal();
		if (principal instanceof UserDetails) {
			username = ((UserDetails) principal).getUsername();
		}
		return username;
	}
	
	/**
	 * 获取当前用户的授权店铺
	 *
	 * @return
	 */
	public static List<String> getAuthorizedShops() {
		Authentication authentication = getAuthentication();
		if (Objects.nonNull(authentication)) {
			if (authentication instanceof JwtAuthenticationToken) {
				JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) authentication;
				List<String> authorizedShops = jwtAuthenticationToken.getAuthorizedShops();
				if (Objects.isNull(authorizedShops)) {
					//查询数据库
					SysUserService userService = SpringContextUtil.getBean(SysUserService.class);
					return userService.findByName(jwtAuthenticationToken.getName()).getAuthorizedShops();
				}
				return authorizedShops;
			}
			if (authentication instanceof UsernamePasswordAuthenticationToken) {
				return ((JwtUserDetails) authentication.getPrincipal()).getAuthorizedShops();
			}
		}
		return Collections.emptyList();
	}
}
